package com.koicarp;

import com.koicarp.university.graduate.service.dao.GraduateStatusDao;
import com.koicarp.university.graduate.service.dto.bigView.BayesSampleDto;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.Vector;
/**
 * @auther liutao
 * @Date 2020-11-16 10:52:49
 */
@Slf4j
@SpringBootTest
public class Bayes {
    @Autowired
    private GraduateStatusDao graduateStatusDao;

//    static Vector<String> indata = new Vector<>();//读入数据
    private static List<BayesSampleDto> list = new ArrayList<>();
    private static Vector<BayesSampleDto> catagory_employment = new Vector<>();//存储就业的所有数据
    private static Vector<BayesSampleDto> catagory_disEmployment = new Vector<>();//存储未就业的所有数据
    private static double p_e = 0.0;
    private static double p_dis_e = 0.0;

    public static void init(List<BayesSampleDto> newList){
        list = newList;
        pretreatment(list);
        p_e = (double) catagory_employment.size() / (double) (list.size());//表示概率p（R）
        p_dis_e = (double) catagory_disEmployment.size() / (double) (list.size());//表示概率p（B）
    }
//    public static boolean loadData(List<BayesSampleDto> list) {//加载测试的数据文件
//        list = graduateStatusDao.selectForBayes();
//        if (list.size()==0){
//            return false;
//        }
//        return true;
////        try {
////            Scanner in = new Scanner(new File(url));//读入文件
////            while (in.hasNextLine()) {
////                String str = in.nextLine();//将文件的每一行存到str的临时变量中
////                indata.add(str);//将每一个样本点的数据追加到Vector 中
////            }
////            return true;
////        } catch (Exception e) { //如果出错返回false
////            return false;
////        }
//    }

    public static void pretreatment(List<BayesSampleDto> list) {   //数据预处理，将原始数据中的每一个属性值提取出来存放到Vector<double[]>  data中
        int i=0;
        while (i < list.size()){
            switch (list.get(i).getIfEmployment()){
                case 1:{
                    catagory_employment.add(list.get(i));
                    break;
                }
                case 0:{
                    catagory_disEmployment.add(list.get(i));
                    break;
                }
            }
            i++;
        }
        //        int i = 0;
//        String t;
//        while (i < list.size()) {//取出indata中的每一行值
//            int[] tem = new int[5];
//            t = indata.get(i);
//            String[] sourceStrArray = t.split(",", 6);//使用字符串分割函数提取出各属性值
//            switch (sourceStrArray[0]) {
//                case "就业": {
//                    for (int j = 1; j < 6; j++) {
//                        if(sourceStrArray[j].equals("计算机科学与技术")){
//                            tem[j-1]=1;
//                        }else{
//                            tem[j - 1] = Integer.parseInt(sourceStrArray[j]);
//                        }
//                    }
//                    catagory_employment.add(tem);
//                    break;
//                }
//                case "未就业": {
//                    for (int j = 1; j < 6; j++) {
//                        if(sourceStrArray[j].equals("计算机科学与技术")){
//                            tem[j-1]=1;
//                        }else{
//                            tem[j - 1] = Integer.parseInt(sourceStrArray[j]);
//                        }
//                    }
//                    catagory_disEmployment.add(tem);
//                    break;
//                }
//            }
//            i++;
//        }
    }

    public static double bayes(BayesSampleDto bayesSampleDto, Vector<BayesSampleDto> catagory) {
        double[] ai_y = new double[5];
        int[] sum_ai = new int[5];
//        int[] x = new int[5];
//        x[0] = bayesSampleDto.getIfCadre();
//        x[1] = bayesSampleDto.getEnglishLevel();
//        x[2] = bayesSampleDto.getComputerLevel();
//        x[3] = bayesSampleDto.getScholarshipNum();
//        x[4] = Integer.parseInt(bayesSampleDto.getSpecialityId());
//        for (int i = 0; i < 5; i++) {
//
//            for (int j = 0; j < catagory.size(); j++) {
//                if (x[i] == catagory.get(j))
//                    sum_ai[i]++;
//            }
//        }
        for (int j = 0; j < catagory.size(); j++) {
            if (bayesSampleDto.getIfCadre().equals(catagory.get(j).getIfCadre()))
                sum_ai[0]++;
            if (bayesSampleDto.getEnglishLevel().equals(catagory.get(j).getEnglishLevel()))
                sum_ai[1]++;
            if (bayesSampleDto.getComputerLevel().equals(catagory.get(j).getComputerLevel()))
                sum_ai[2]++;
            if (bayesSampleDto.getScholarshipNum().equals(catagory.get(j).getScholarshipNum()))
                sum_ai[3]++;
            if (bayesSampleDto.getSpecialityId().equals(catagory.get(j).getSpecialityId()))
                sum_ai[4]++;
        }
        for (int i = 0; i < 5; i++) {
            ai_y[i] = (double) sum_ai[i] / (double) catagory.size();
        }
        return ai_y[0] * ai_y[1] * ai_y[2] * ai_y[3]*ai_y[4];
    }

    /**
     * 输入一组数据判断是否能就业
     * @param bayesSampleDto 毕业生状态数据dto
     * @return true 为能够就业，false为预测不能就业
     */
    public static boolean employment(BayesSampleDto bayesSampleDto){
        double x_in_e = bayes(bayesSampleDto, catagory_employment) * p_e;
        double x_in_dis_e = bayes(bayesSampleDto, catagory_disEmployment) * p_dis_e;

        if (x_in_e == Math.max(x_in_e, x_in_dis_e)) {
            return true;
        } else if (x_in_dis_e==Math.max(x_in_e, x_in_dis_e)) {
            return false;
        }else{
            log.error("朴素贝叶斯算法错误，请查找原因");
            return false;
        }
    }
    @Test
    public void contest() {
        List<BayesSampleDto> dtoList = graduateStatusDao.selectForBayes();
        init(dtoList);
        BayesSampleDto bayesSampleDto = new BayesSampleDto();
        bayesSampleDto.setName("liutao");
        bayesSampleDto.setIfCadre(0);
        bayesSampleDto.setComputerLevel(0);
        bayesSampleDto.setEnglishLevel(0);
        bayesSampleDto.setScholarshipNum(0);
        bayesSampleDto.setSpecialityId("1");
        System.out.println(employment(bayesSampleDto));

//        loadData("E:\\IDEA\\university-graduate\\university-graduate-service\\src\\main\\resources\\graduate.txt");
//        pretreatment(list);
//
//
//        int[] x = new int[5];
//
//        int sumR=0, sumL=0, sumB=0;
//        double correct=0;
//
//
//        System.out.println("请输入样本x格式如下：\n 1 1 1 1\n");
//        int r = 0;
//        while (r < list.size()) {
//
////            for (int i = 0; i < 5; i++) {
////                //读取数字放入数组的第i个元素
////                String tmp =indata.get(r).split(",", 6)[i + 1];
////                if (tmp.equals("计算机科学与技术")) {
////                    x[i] = 1;
////                    continue;
////                }
////                x[i] = Integer.parseInt(tmp);
////            }
////            double x_in_e = bayes(x, catagory_employment) * p_e;
////            double x_in_dis_e = bayes(x, catagory_disEmployment) * p_dis_e;
//            double x_in_e = bayes(list.get(r), catagory_employment) * p_e;
//            double x_in_dis_e = bayes(list.get(r), catagory_disEmployment) * p_dis_e;
//            //比较就业余未就业的概率大小
////            String is_jy = indata.get(r).split(",",6)[0];
//            int is_jy = list.get(r).getIfEmployment();
//            if (x_in_e == Math.max(x_in_e, x_in_dis_e)) {
//                System.out.println("输入的第"+r+"样本推断是属于类别：就业");
//                sumB++;
//                if(is_jy==1)
//                    correct++;
//            } else if (x_in_dis_e==Math.max(x_in_e, x_in_dis_e)) {
//                System.out.println("输入的第"+r+"样本推断是属于类别：未就业");
//                sumL++;
//                if(is_jy==0)
//                    correct++;
//            }
//            r++;
//        }
//
//        System.out.println("使用训练样本进行分类器检验得到结果统计如下：");
//        System.out.println("未就业类有："+sumL+"    实际有未就业类样本"+catagory_disEmployment.size()+"个");
//        System.out.println("就业类有："+sumB+"      实际有就业类样本"+catagory_employment.size()+"个");
//        System.out.println(correct);
//        System.out.println("分类的正确率为"+correct*1.0/list.size()*100+"%");

    }
}
